import tkinter as tk
from tkinter import ttk, filedialog, messagebox, simpledialog
import socket
import threading
from datetime import datetime
import json
import time
import os
# 导入拆分后的模块
from gui_modules.network_manager import NetworkManager
from gui_modules.file_processor import FileProcessor
from gui_modules.firmware_upgrade import FirmwareUpgrade
from gui_modules.can_upgrade import CANUpgrade

class NetworkClient:
    def __init__(self, root):
        self.root = root
        self.root.title("升控台 V1.6.0")
        self.root.geometry("800x600")
        self.root.configure(bg="#f5f5f5")
        
        # 绑定窗口关闭事件
        self.root.protocol("WM_DELETE_WINDOW", self.on_close)
        
        # 设置应用图标
        try:
            self.root.iconbitmap("network_icon.ico")
        except:
            pass
        
        # 主题颜色
        self.primary_color = "#2c7be5"
        self.secondary_color = "#6c757d"
        self.success_color = "#28a745"
        self.danger_color = "#dc3545"
        self.warning_color = "#ffc107"
        self.info_color = "#17a2b8"
        
        # 超时时间配置
        self.CONNECT_TIMEOUT = 3.0
        self.HANDSHAKE_TIMEOUT = 3.0
        self.DATA_SEND_TIMEOUT = 3.0
        self.RESPONSE_TIMEOUT = 3.0
        
        # 创建样式
        self.style = ttk.Style()
        self.style.configure("TFrame", background="#f5f5f5")
        self.style.configure("TLabel", background="#f5f5f5", font=("微软雅黑", 10))
        self.style.configure("TButton", font=("微软雅黑", 10), padding=6)
        
        # 创建主框架
        self.main_frame = ttk.Frame(self.root, padding=(20, 10))
        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 连接状态
        self.connected = False
        self.socket = None
        
        # 状态变量
        self.timestamp_var = tk.BooleanVar(value=True)
        
        # 初始化状态变量
        self.status_var = tk.StringVar()
        self.status_var.set("状态: 未连接")
        
        # 创建UI组件
        self.create_widgets()
        
        # 初始化所有功能模块
        self.file_processor = FileProcessor(
            self.root,
            self.message_display,
            self.timestamp_var
        )
        self.network_manager = NetworkManager(
            self.root,
            self.message_display,
            self.status_var,
            self.timestamp_var
        )
        self.firmware_upgrade = FirmwareUpgrade(
            self.root,
            self.network_manager,
            self.file_processor,
            self.message_display,
            self.timestamp_var
        )
        self.can_upgrade = CANUpgrade(
            self.root,
            self.network_manager,
            self.message_display,
            self.timestamp_var
        )
        
        # 创建菜单栏（必须在模块初始化之后）
        self.create_menu()
        
        # 配置消息显示样式
        self.setup_message_styles()
        
        # 设置最小窗口大小
        self.root.minsize(550, 450)
        
        self.on_receive_message = None

    def create_widgets(self):
        # 主内容框架
        content_frame = ttk.Frame(self.main_frame)
        content_frame.pack(fill=tk.BOTH, expand=True)
        
        # 左侧连接设置框架
        left_frame = ttk.Frame(content_frame, width=250)
        left_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10))
        
        # 连接设置
        connection_frame = ttk.LabelFrame(left_frame, text="连接设置", padding=10)
        connection_frame.pack(fill=tk.X, pady=(0, 15))
        
        # IP地址输入
        ttk.Label(connection_frame, text="服务器IP:").pack(anchor=tk.W, padx=5, pady=2)
        self.ip_entry = ttk.Entry(connection_frame)
        self.ip_entry.pack(fill=tk.X, padx=5, pady=2)
        self.ip_entry.insert(0, "127.0.0.1")
        
        # 端口输入
        ttk.Label(connection_frame, text="端口:").pack(anchor=tk.W, padx=5, pady=2)
        self.port_entry = ttk.Entry(connection_frame)
        self.port_entry.pack(fill=tk.X, padx=5, pady=2)
        self.port_entry.insert(0, "7878")
        
        # 连接/断开按钮
        btn_frame = ttk.Frame(connection_frame)
        btn_frame.pack(fill=tk.X, pady=5)
        self.connect_btn = ttk.Button(btn_frame, text="连接", command=self.toggle_connection)
        self.connect_btn.pack(side=tk.LEFT, expand=True, padx=2)
        
        # 右侧命令列表框架
        right_frame = ttk.Frame(content_frame)
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
        
        # 命令列表区域
        command_frame = ttk.LabelFrame(right_frame, text="JSON命令列表")
        command_frame.pack(fill=tk.BOTH, expand=True, padx=(10, 0))

        # 主内容框架
        cmd_content_frame = ttk.Frame(command_frame)
        cmd_content_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 命令列表框 (宽度减小)
        self.command_listbox = tk.Listbox(
            cmd_content_frame, 
            height=10, 
            width=30,
            font=("Consolas", 10)
        )
        self.command_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # 右侧按钮框架
        cmd_btn_frame = ttk.Frame(cmd_content_frame)
        cmd_btn_frame.pack(side=tk.RIGHT, fill=tk.Y, padx=(5,0))

        # 垂直排列的按钮
        ttk.Button(cmd_btn_frame, text="添加", command=self.add_command).pack(fill=tk.X, pady=2)
        ttk.Button(cmd_btn_frame, text="删除", command=self.remove_command).pack(fill=tk.X, pady=2)
        ttk.Button(cmd_btn_frame, text="上移", command=self.move_command_up).pack(fill=tk.X, pady=2)
        ttk.Button(cmd_btn_frame, text="下移", command=self.move_command_down).pack(fill=tk.X, pady=2)
        ttk.Button(
            cmd_btn_frame, 
            text="发送选中", 
            command=self.send_selected_command,
            style="Accent.TButton"
        ).pack(fill=tk.X, pady=2)

        # 绑定双击编辑事件
        self.command_listbox.bind("<Double-Button-1>", self.edit_selected_command)
        
        # 加载保存的命令(必须在command_listbox创建之后)
        self.load_commands()
        
        # 消息显示区域
        message_frame = ttk.LabelFrame(self.main_frame, text="消息", padding=5)
        message_frame.pack(fill=tk.BOTH, expand=False, pady=(0, 10))
        message_frame.pack_propagate(False)
        message_frame.config(height=200)
        
        scrollbar = ttk.Scrollbar(message_frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        self.message_display = tk.Text(message_frame, height=15, state=tk.DISABLED)
        self.message_display.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=self.message_display.yview)

        # 消息输入区域
        input_frame = ttk.Frame(self.main_frame)
        input_frame.pack(fill=tk.X, pady=(0, 10))
        
        self.message_entry = ttk.Entry(input_frame)
        self.message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
        
        send_btn = ttk.Button(
            input_frame,
            text="发送",
            command=self.send_user_message,
            width=10
        )
        send_btn.pack(side=tk.RIGHT)
        
        # 状态栏
        status_bar = ttk.Frame(self.main_frame, height=30)
        status_bar.pack(fill=tk.X, pady=(10, 0))

        # 连接状态指示灯
        self.connection_led = tk.Canvas(status_bar, width=20, height=20, bg="red", bd=0, highlightthickness=0)
        self.connection_led.pack(side=tk.LEFT, padx=(10, 5))
        
        # 确保状态栏组件创建完成后再设置状态
        self.status_var.set("状态: 未连接")

        self.status_var = tk.StringVar()
        self.status_var.set("状态: 未连接")
        ttk.Label(status_bar, textvariable=self.status_var).pack(side=tk.LEFT, padx=5)

        # 添加项目名称和版本号
        version_label = ttk.Label(
            status_bar, 
            text="PyUpConsole (升控台) v1.5.0 beta",
            font=("微软雅黑", 9)
        )
        version_label.pack(side=tk.RIGHT, padx=10)

    def create_menu(self):
        menubar = tk.Menu(self.root)
        self.root.config(menu=menubar)
        
        # 文件菜单
        file_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="文件", menu=file_menu)
        file_menu.add_command(label="打开并加载文件", command=self.open_and_load_file)
        file_menu.add_command(label="查看已加载文件", command=self._show_loaded_files)
        file_menu.add_command(label="清除已加载文件", command=self._clear_loaded_files)
        file_menu.add_separator()
        file_menu.add_command(label="退出", command=self.root.quit)
        
        # 工具菜单
        tools_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="工具", menu=tools_menu)
        tools_menu.add_command(label="文件信息", command=self._show_combined_file_info)
        tools_menu.add_command(label="导出为BIN文件", command=self.file_processor.export_hex_to_bin)
        tools_menu.add_command(label="导出为HEX文件", command=self.file_processor.export_bin_to_hex)
        tools_menu.add_command(label="显示BIN文件内容", command=self.file_processor.show_bin_content)
        tools_menu.add_command(label="执行升级流程", command=self.firmware_upgrade.show_upgrade_dialog)
        tools_menu.add_command(label="CAN转发升级", command=self.can_upgrade.show_can_upgrade_dialog)

    # 保留核心网络功能方法
    def toggle_connection(self):
        if not self.connected:
            self.connect_to_server()
        else:
            self.disconnect_from_server()
    
    def connect_to_server(self):
        ip = self.ip_entry.get()
        port = self.port_entry.get()
        if self.network_manager.connect_to_server(ip, port):
            self.connected = True
            self.connect_btn.config(text="断开")
            self.connection_led.config(bg="green")
            self.connection_led.update()
        else:
            self.connected = False
            self.connect_btn.config(text="连接")
            self.connection_led.config(bg="red")
            self.connection_led.update()
    
    def disconnect_from_server(self):
        self.network_manager.disconnect_from_server()
        self.connected = False
        self.connect_btn.config(text="连接")
        self.connection_led.config(bg="red")
        self.connection_led.update()
    
    def receive_messages(self):
        while self.connected:
            try:
                data = self.socket.recv(1024)
                if not data:
                    break
                message = data.decode('utf-8')
                self.display_received_message(message)
            except:
                break
        
        self.disconnect_from_server()

    def display_received_message(self, message):
        self.message_display.config(state=tk.NORMAL)
        self.message_display.insert(tk.END, f"服务器: {message}\n")
        self.message_display.config(state=tk.DISABLED)
        self.message_display.see(tk.END)
        
    def _show_combined_file_info(self):
        """显示合并的文件信息"""
        # 检查是否有加载的文件
        if not self.file_processor.hex_loader and not self.file_processor.bin_loader:
            messagebox.showinfo("信息", "请先加载HEX或BIN文件")
            return
        
        # 创建对话框
        info_window = tk.Toplevel(self.root)
        info_window.title("文件信息")
        info_window.geometry("600x400")
        info_window.resizable(True, True)
        
        # 创建笔记本控件
        notebook = ttk.Notebook(info_window)
        notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 添加HEX文件信息标签页
        if self.file_processor.hex_loader:
            hex_frame = ttk.Frame(notebook)
            notebook.add(hex_frame, text="HEX文件信息")
            
            # 添加HEX文件信息
            hex_text = tk.Text(hex_frame, wrap=tk.WORD)
            hex_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
            
            # 获取HEX文件信息
            hex_info = self.file_processor.get_hex_info()
            hex_text.insert(tk.END, hex_info)
            hex_text.config(state=tk.DISABLED)
        
        # 添加BIN文件信息标签页
        if self.file_processor.bin_loader:
            bin_frame = ttk.Frame(notebook)
            notebook.add(bin_frame, text="BIN文件信息")
            
            # 添加BIN文件信息
            bin_text = tk.Text(bin_frame, wrap=tk.WORD)
            bin_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
            
            # 获取BIN文件信息
            bin_info = self.file_processor.get_bin_info()
            bin_text.insert(tk.END, bin_info)
            bin_text.config(state=tk.DISABLED)
    
    def open_and_load_file(self):
        """打开文件并根据扩展名自动加载到内存"""
        file_path = self.file_processor.select_file()
        if file_path:
            # 根据文件扩展名判断类型
            if file_path.lower().endswith('.hex'):
                self.file_processor.load_hex_file(file_path)
            elif file_path.lower().endswith('.bin'):
                self.file_processor.load_bin_file(file_path)
            else:
                messagebox.showwarning("警告", "不支持的文件类型，请选择.hex或.bin文件")
                
    def _show_file_info(self, file_type):
        """Helper method to display file information"""
        info = None
        if file_type == 'hex':
            info = self.file_processor.get_hex_info()
        else:
            info = self.file_processor.get_bin_info()
            
        if info:
            self.message_display.config(state=tk.NORMAL)
            self.message_display.insert(tk.END, f"{file_type.upper()}文件信息:\n")
            for key, value in info.items():
                self.message_display.insert(tk.END, f"  {key}: {value}\n")
            self.message_display.config(state=tk.DISABLED)
            self.message_display.see(tk.END)
        else:
            messagebox.showwarning("警告", f"没有加载{file_type.upper()}文件")

    def _clear_loaded_files(self):
        """逐个选择清除已加载的文件"""
        # 创建选择对话框
        dialog = tk.Toplevel(self.root)
        dialog.title("选择要清除的文件")
        dialog.geometry("400x200")
        dialog.resizable(False, False)
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 居中显示
        dialog.update_idletasks()
        width = dialog.winfo_width()
        height = dialog.winfo_height()
        x = (dialog.winfo_screenwidth() // 2) - (width // 2)
        y = (dialog.winfo_screenheight() // 2) - (height // 2)
        dialog.geometry('{}x{}+{}+{}'.format(width, height, x, y))
        
        # 创建文件选择变量和复选框列表
        file_vars = []
        file_loaders = []
        
        # 检查是否有已加载的HEX文件
        if hasattr(self.file_processor, 'hex_loader') and self.file_processor.hex_loader:
            hex_path = getattr(self.file_processor.hex_loader, 'file_path', '未知路径')
            hex_filename = os.path.basename(hex_path)
            var = tk.BooleanVar()
            file_vars.append((var, f"HEX文件: {hex_filename}"))
            file_loaders.append(('hex', var))
        
        # 检查是否有已加载的BIN文件
        if hasattr(self.file_processor, 'bin_loader') and self.file_processor.bin_loader:
            bin_path = getattr(self.file_processor.bin_loader, 'file_path', '未知路径')
            bin_filename = os.path.basename(bin_path)
            var = tk.BooleanVar()
            file_vars.append((var, f"BIN文件: {bin_filename}"))
            file_loaders.append(('bin', var))
        
        if not file_vars:
            ttk.Label(dialog, text="没有已加载的文件").pack(padx=20, pady=10)
            ttk.Button(dialog, text="确定", command=dialog.destroy).pack(pady=10)
            return
        
        # 创建复选框
        for var, text in file_vars:
            check = ttk.Checkbutton(dialog, text=text, variable=var)
            check.pack(anchor=tk.W, padx=20, pady=5)
        
        # 确认按钮
        def confirm_clear():
            cleared = False
            
            for loader_type, var in file_loaders:
                if var.get():
                    if loader_type == 'hex':
                        self.file_processor.hex_loader = None
                    else:
                        self.file_processor.bin_loader = None
                    cleared = True
            
            if cleared:
                messagebox.showinfo("成功", "已清除选中的文件")
            else:
                messagebox.showinfo("提示", "未选择任何文件")
            
            dialog.destroy()
        
        btn_frame = ttk.Frame(dialog)
        btn_frame.pack(pady=10)
        
        ttk.Button(btn_frame, text="确认", command=confirm_clear).pack(side=tk.LEFT, padx=10)
        ttk.Button(btn_frame, text="取消", command=dialog.destroy).pack(side=tk.LEFT, padx=10)

    def _show_loaded_files(self):
        """显示已加载的文件信息"""
        loaded_files = []
        
        # 检查HEX文件
        if hasattr(self.file_processor, 'hex_loader') and self.file_processor.hex_loader:
            hex_path = getattr(self.file_processor.hex_loader, 'file_path', '未知路径')
            loaded_files.append(f"HEX文件: {hex_path}")
        
        # 检查BIN文件
        if hasattr(self.file_processor, 'bin_loader') and self.file_processor.bin_loader:
            bin_path = getattr(self.file_processor.bin_loader, 'file_path', '未知路径')
            loaded_files.append(f"BIN文件: {bin_path}")
        
        if not loaded_files:
            messagebox.showinfo("已加载文件", "没有加载任何HEX或BIN文件")
            return
        
        # 创建对话框显示已加载文件
        files_window = tk.Toplevel(self.root)
        files_window.title("已加载文件")
        files_window.geometry("400x200")
        files_window.resizable(True, True)
        
        # 创建列表框显示文件
        listbox = tk.Listbox(files_window, font=("微软雅黑", 10))
        listbox.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        for file_info in loaded_files:
            listbox.insert(tk.END, file_info)
        
        # 添加关闭按钮
        close_btn = ttk.Button(files_window, text="关闭", command=files_window.destroy)
        close_btn.pack(pady=5)

    def setup_message_styles(self):
        """Configure text styles for message display"""
        self.message_display.tag_config("timestamp", foreground="gray")
        self.message_display.tag_config("server", foreground="blue")
        self.message_display.tag_config("sent", foreground="green")
        self.message_display.tag_config("error", foreground="red")
        self.message_display.tag_config("warning", foreground="orange")
        self.message_display.tag_config("info", foreground="darkcyan")
        self.message_display.tag_config("user", foreground="purple")
        self.message_display.tag_config("command", foreground="darkgreen")

    def add_command(self, event=None):
        """添加新命令到列表"""
        dialog = tk.Toplevel(self.root)
        dialog.title("添加JSON命令")
        
        # 计算对话框位置(居中于鼠标点击位置)
        if event:
            x = self.root.winfo_pointerx() - 150  # 对话框宽度的一半
            y = self.root.winfo_pointery() - 125  # 对话框高度的一半
            dialog.geometry(f"300x250+{x}+{y}")
        else:
            dialog.geometry("300x250")  # 默认居中
        
        # 主框架
        main_frame = ttk.Frame(dialog, padding=(10, 10, 10, 5))
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 标签和输入框
        input_frame = ttk.Frame(main_frame)
        input_frame.pack(fill=tk.X, pady=(0, 5))
        
        ttk.Label(input_frame, text="JSON命令:", font=("微软雅黑", 9)).pack(side=tk.LEFT)
        
        # 文本区域框架
        text_frame = ttk.Frame(main_frame, relief=tk.SUNKEN, borderwidth=1)
        text_frame.pack(fill=tk.BOTH, expand=True)
        
        scrollbar = ttk.Scrollbar(text_frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        text = tk.Text(
            text_frame, 
            height=12, 
            width=30,
            font=("Consolas", 9),
            yscrollcommand=scrollbar.set,
            padx=3,
            pady=3
        )
        text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=text.yview)
        
        # 按钮框架
        btn_frame = ttk.Frame(main_frame)
        btn_frame.pack(fill=tk.X, pady=(15, 0))
        
        def on_ok():
            command = text.get("1.0", tk.END).strip()
            if command:
                try:
                    json.loads(command)
                    self.command_listbox.insert(tk.END, command)
                    dialog.destroy()
                except json.JSONDecodeError:
                    messagebox.showerror("错误", "无效的JSON格式")
        
        ttk.Button(btn_frame, text="确定", command=on_ok).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="取消", command=dialog.destroy).pack(side=tk.LEFT)
        
        dialog.transient(self.root)
        dialog.grab_set()
        dialog.wait_window(dialog)

    def remove_command(self):
        """从列表中删除选中命令"""
        selection = self.command_listbox.curselection()
        if selection:
            self.command_listbox.delete(selection[0])

    def move_command_up(self):
        """将选中命令上移一位"""
        selection = self.command_listbox.curselection()
        if selection and selection[0] > 0:
            index = selection[0]
            command = self.command_listbox.get(index)
            self.command_listbox.delete(index)
            self.command_listbox.insert(index-1, command)
            self.command_listbox.selection_set(index-1)

    def move_command_down(self):
        """将选中命令下移一位"""
        selection = self.command_listbox.curselection()
        if selection and selection[0] < self.command_listbox.size()-1:
            index = selection[0]
            command = self.command_listbox.get(index)
            self.command_listbox.delete(index)
            self.command_listbox.insert(index+1, command)
            self.command_listbox.selection_set(index+1)

    def load_commands(self):
        """从文件加载保存的命令"""
        try:
            with open('commands.json', 'r', encoding='utf-8') as f:
                commands = json.load(f)
                for cmd in commands:
                    self.command_listbox.insert(tk.END, cmd)
        except (FileNotFoundError, json.JSONDecodeError):
            pass  # 文件不存在或格式错误时忽略

    def save_commands(self):
        """保存命令列表到文件"""
        commands = [self.command_listbox.get(i) for i in range(self.command_listbox.size())]
        try:
            with open('commands.json', 'w', encoding='utf-8') as f:
                json.dump(commands, f, ensure_ascii=False, indent=2)
        except IOError as e:
            messagebox.showerror("错误", f"保存命令失败: {str(e)}")

    def on_close(self):
        """窗口关闭事件处理"""
        self.save_commands()
        self.root.destroy()

    def edit_selected_command(self, event):
        """双击编辑选中命令"""
        selection = self.command_listbox.curselection()
        if selection:
            index = selection[0]
            old_command = self.command_listbox.get(index)
            
            dialog = tk.Toplevel(self.root)
            dialog.title("编辑JSON命令")
            dialog.geometry("300x250")
            
            # 主框架
            main_frame = ttk.Frame(dialog, padding=(10, 10, 10, 5))
            main_frame.pack(fill=tk.BOTH, expand=True)
            
            # 文本区域框架
            text_frame = ttk.Frame(main_frame, relief=tk.SUNKEN, borderwidth=1)
            text_frame.pack(fill=tk.BOTH, expand=True)
            
            scrollbar = ttk.Scrollbar(text_frame)
            scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
            
            text = tk.Text(
                text_frame, 
                height=12, 
                width=30,
                font=("Consolas", 9),
                yscrollcommand=scrollbar.set,
                padx=3,
                pady=3
            )
            text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
            text.insert("1.0", old_command)
            scrollbar.config(command=text.yview)
            
            # 按钮框架
            btn_frame = ttk.Frame(main_frame)
            btn_frame.pack(fill=tk.X, pady=(15, 0))
            
            def on_ok():
                new_command = text.get("1.0", tk.END).strip()
                if new_command:
                    try:
                        json.loads(new_command)
                        self.command_listbox.delete(index)
                        self.command_listbox.insert(index, new_command)
                        dialog.destroy()
                    except json.JSONDecodeError:
                        messagebox.showerror("错误", "无效的JSON格式")
            
            ttk.Button(btn_frame, text="确定", command=on_ok).pack(side=tk.LEFT, padx=5)
            ttk.Button(btn_frame, text="取消", command=dialog.destroy).pack(side=tk.LEFT)
            
            dialog.transient(self.root)
            dialog.grab_set()
            dialog.wait_window(dialog)

    def send_selected_command(self):
        """发送选中的JSON命令"""
        selection = self.command_listbox.curselection()
        if selection:
            command = self.command_listbox.get(selection[0])
            if self.network_manager.send_message(command):
                self.message_display.config(state=tk.NORMAL)
                if self.timestamp_var.get():
                    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    self.message_display.insert(tk.END, f"[{timestamp}] ", "timestamp")
                self.message_display.insert(tk.END, f"我: {command}\n", "user")
                self.message_display.config(state=tk.DISABLED)
                self.message_display.see(tk.END)

    def send_user_message(self):
        """发送用户输入的消息"""
        message = self.message_entry.get()
        if message and self.network_manager.send_message(message):
            self.message_display.config(state=tk.NORMAL)
            if self.timestamp_var.get():
                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                self.message_display.insert(tk.END, f"[{timestamp}] ", "timestamp")
            self.message_display.insert(tk.END, f"我: {message}\n", "user")
            self.message_display.config(state=tk.DISABLED)
            self.message_display.see(tk.END)
            self.message_entry.delete(0, tk.END)

if __name__ == "__main__":
    root = tk.Tk()
    app = NetworkClient(root)
    root.mainloop()
